Software testing and validation often require substituting certain components of tested system with simplified replacements. This is usually done to provide a substitute for not yet ready components of the software under test, to isolate tested component from other possibly multi layered parts of the software under test, and/or to separate test code from production code. In the case of providing a substitute for not yet ready components, the substituting code has two roles: it enables assembling the test binary which would otherwise be impossible because of missing definitions, and it allows providing simplified implementation which can interact with tested components. In the case of isolating tested component, the roles of the substituting code are to limit the effort related to test environment setup by simplifying the logic of replaced component, to provide convenient interface to control side effects (e.g. return value), and to provide convenient interface for asserting expectations.
Test stubs (or stubs) are one kind of substituting code that simulate the behaviors of software components or modules that a program under test communicates with or depends on. Stubs act as temporary replacement for a called component and provide the same output as the actual product or software. Test stubs are static (hard-wired) and provide canned results to calls made during the test, however, test stubs usually do not respond to anything outside what's programmed therein for the test, that is, they depend on the test case and thus are limited in their functionality. Moreover, there is usually one test stub for all the test cases. This makes the management of the test system more difficult. For example, if any test case is modified, the test stub has to be modified as well. Test stubs are mainly used in incremental testing's top-down approach.
Mock objects are simulated objects that imitate the behavior of real objects in a controlled way, in object-oriented programming. A programmer typically creates a mock object to test the behavior of some other object. In a unit test, mock objects can simulate the behavior of complex real objects. As a result, mock objects are useful when a real object is impractical or impossible to incorporate into a unit test. Mock objects are limited to objects and thus to object oriented programming.
Moreover, mock objects are tightly related to their corresponding real objects and have the same interface as the real objects they mimic. This allows the software under test to remain unaware of whether it is using a real object or a mock object. Mock objects allow the programmer to specify which, and in what order, methods will be invoked on a mock object, what parameters will be passed to them, and what values will be returned and therefore are dynamic in their nature. The over-use of mock objects can closely couple the unit tests to the actual implementation of the software that is being tested, which affects testing a method's internal implementation rather than its external behavior, in unit tests.
Over-use of mock objects as part of a suite of unit tests can also result in a dramatic increase in the amount of maintenance that needs to be performed on the tests themselves during system evolution. Conversely, simply mocking one method might require far less configuration than setting up an entire real class and therefore reduce maintenance needs. Furthermore, mock objects have to accurately model the behavior of the object they are mocking, which can be difficult to achieve if the object being mocked comes from another developer or project, or if it has not even been written yet. If the behavior is not modeled correctly, then the unit tests may register a pass even though a failure would occur at run time under the same conditions that the unit test is exercising and thus rendering the unit test inaccurate.